library(data.table)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
data.table 1.12.8 using 2 threads (see ?getDTthreads).  Latest news: r-datatable.com
library(ggplot2)
Registered S3 method overwritten by 'dplyr':
  method           from
  print.rowwise_df     
library(beanplot) # for beanplots
library(gridExtra) # to combine ggplots together
library(grid) # to combine ggplots together


knitr::opts_knit$set(root.dir = rprojroot::find_rstudio_root_file()) # tell RStudio to use project root directory as the root for this notebook. Needed since we are storing code in a separate directory.

Load data

# BioTime
load('data/biotime_blowes/bt_malin.Rdata')
bt <- data.table(bt_malin); rm(bt_malin)

# Temperature average, trends, and seasonality
temperature <- fread('output/temperature_byrarefyID.csv.gz')

# microclimates
microclim <- fread('output/microclimates.csv.gz', drop = 1)

# NPP
npp <- fread('output/npplandocean.csv.gz')

# Body size
bs <- fread('output/mass_byrarefyid.csv.gz', drop = 1)
bs[, ':='(STUDY_ID = NULL, REALM = NULL, taxa_mod = NULL)] # remove unnecessary columns 

# Mobility
speed <- fread('output/speed_byrarefyID.csv.gz', drop = 1)
speed[, ':='(STUDY_ID = NULL, REALM = NULL, taxa_mod = NULL)] # remove unnecessary columns 

# Lifespan
lsp <- fread('output/lifespan_byrarefyID.csv.gz')

# CTI
cti <- fread('output/cti_byrarefyID.csv.gz')
    
# consumer vs. producer
cons <- fread('output/metab_feed_byspecies.csv.gz')
consfrac <- cons[, .(consfrac = sum(feeding == 'consumer')/.N), by = rarefyID] # fraction of species in each study that are consumers

# richness
rich <- fread('output/richness_by_rarefyID.csv.gz') # number of species

# endotherm vs. ectotherm
endo <- fread('output/metab_feed_byspecies.csv.gz') # endotherm vs. ectotherm classifications
endofrac <- endo[, .(endofrac = sum(metab != 'ecto')/.N), by = rarefyID]
rm(endo)

# human impact
human <- fread('output/humanimpact_by_rarefyID.csv.gz')

# %veg
veg <- as.data.table(readRDS('output/vct_by_rarefyID.rds'))
veg[, veg := (`tree cover % (mean)` + 0.5 * `non-tree veg. % (mean)`)/100] # veg index from 0 (all non-veg) to 1 (all tree). Non-tree veg counts as 0.5.

Plot a turnover example

#bt[, .(n = .N), by = rarefyID][n > 50,]

ggplot(bt[rarefyID == '339_1085477'], aes(YEAR, Jtu_base)) +
    geom_point() +
    geom_smooth(method = 'lm') +
    xlab('Year') + ylab('Jaccard dissimilarity')

Compare covariates across realms

i <- trends[, !duplicated(rarefyID)]; sum(i)
[1] 53013
par(mfrow=c(5,3))
beanplot(rarefyID_y ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Latitude (degN)', ll = 0.05)
beanplot(tempave ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Temperature (degC)', ll = 0.05)
beanplot(tempave_metab ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Metabolic Temperature (degC)', ll = 0.05, bw = 'nrd0') # nrd0 bandwidth to calculation gap
beanplot(seas ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Seasonality (degC)', ll = 0.05)
beanplot(microclim ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Microclimates (degC)', ll = 0.05)
log="y" selected
beanplot(temptrend ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Temperature trend (degC/yr)', ll = 0.05)
beanplot(mass_mean_weight ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Mass (g)', ll = 0.05, log = 'y')
beanplot(speed_mean_weight +1 ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Speed (km/hr)', ll = 0.05, log = 'y')
beanplot(lifespan_mean_weight ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Lifespan (yr)', ll = 0.05, log = 'y')
#beanplot(consfrac ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Consumers (fraction)', ll = 0.05, log = '') # too sparse
#beanplot(endofrac ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Endotherms (fraction)', ll = 0.05, log = '') # too sparse
beanplot(Nspp ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Number of species', ll = 0.05, log = 'y')
beanplot(thermal_bias ~ REALM, data = trends[i & !is.na(thermal_bias),], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'Thermal bias (degC)', ll = 0.05)
beanplot(npp ~ REALM, data = trends[i,], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'NPP', ll = 0.05)
log="y" selected
beanplot(veg ~ REALM, data = trends[i & REALM !='Marine',], what = c(1,1,1,1), col = c("#CAB2D6", "#33A02C", "#B2DF8A"), border = "#CAB2D6", ylab = 'NPP', ll = 0.05)

Marine are in generally warmer locations (seawater doesn’t freeze) Marine have much lower seasonality. Marine and freshwater have some very small masses (plankton), but much of dataset is similar to terrestrial. Marine has a lot of slow, crawling organisms, but land has plants. Land also has birds (fast).

Plot turnover vs. temperature

Time-series length and temperature trend?

ggplot(trends, aes(temptrend, nyrBT)) +
  geom_point() +
  geom_smooth() +
  scale_y_log10()

Plot turnover vs. explanatory variables

Lines are ggplot smoother fits.

Strong trends with temperature change, but trends are pretty symmetric around no trend in temperature, which implies warming or cooling drives similar degree of community turnover. Some indication of less turnover for larger organisms (mass) Higher turnover on land with higher seasonality? More turnover for shorter-lived organisms? No really clear differences among realms.

Write out

write.csv(trends, gzfile('output/turnover_w_covariates.csv.gz'), row.names = FALSE)

Useful variables

# realm that combined Terrestrial and Freshwater, for interacting with human impact
trends[, REALM2 := REALM]
levels(trends$REALM2) = list(TerrFresh = "Freshwater", TerrFresh = "Terrestrial", Marine = "Marine")

# group Marine invertebrates/plants in with All
trends[, taxa_mod2 := taxa_mod]
trends[taxa_mod == 'Marine invertebrates/plants', taxa_mod2 := 'All']

Log-transform some variables, then center and scale.

trends[, tempave.sc := scale(tempave)]
trends[, tempave_metab.sc := scale(tempave_metab)]
trends[, seas.sc := scale(seas)]
trends[, microclim.sc := scale(log(microclim))]
trends[, temptrend.sc := scale(temptrend, center = FALSE)]
trends[, temptrend_abs.sc := scale(abs(temptrend), center = FALSE)] # do not center, so that 0 is still 0 temperature change
trends[, mass.sc := scale(log(mass_mean_weight))]
trends[, speed.sc := scale(log(speed_mean_weight+1))]
trends[, lifespan.sc := scale(log(lifespan_mean_weight))]
trends[, consumerfrac.sc := scale(consfrac)]
trends[, endothermfrac.sc := scale(endofrac)]
trends[, nspp.sc := scale(log(Nspp))]
trends[, thermal_bias.sc := scale(thermal_bias)]
trends[, npp.sc := scale(log(npp))]
trends[, veg.sc := scale(log(veg+1))]
trends[, human_bowler.sc := scale(log(human_bowler+1)), by = REALM2] # separate scaling by realm
trends[REALM2 == 'TerrFresh', human_footprint.sc := scale(log(human_venter+1))]
trends[REALM2 == 'Marine', human_footprint.sc := scale(log(human_halpern))]

Do the variables look ok?

Unscaled

# histograms to examine
cexmain = 0.6
par(mfrow = c(5,4))
invisible(trends[, hist(minyrBT, main = 'Start year', cex.main = cexmain)])
invisible(trends[, hist(maxyrBT - minyrBT, main = 'Duration (years)', cex.main = cexmain)])
invisible(trends[, hist(nyrBT, main = 'Number of sampled years', cex.main = cexmain)])
invisible(trends[, hist(mass_mean_weight, main = 'Mass (g)', cex.main = cexmain)])
invisible(trends[, hist(speed_mean_weight, main = 'Speed (km/hr)', cex.main = cexmain)])
invisible(trends[, hist(lifespan_mean_weight, main = 'Lifespan (yr)', cex.main = cexmain)])
invisible(trends[, hist(tempave_metab, main = 'Metabolic temperature (°C)', cex.main = cexmain)])
invisible(trends[, hist(consfrac, main = 'Consumers (fraction)', cex.main = cexmain)])
invisible(trends[, hist(endofrac, main = 'Endotherms (fraction)', cex.main = cexmain)])
invisible(trends[, hist(tempave, main = 'Environmental temperature (°C)', cex.main = cexmain)])
invisible(trends[, hist(temptrend, main = 'Temperature trend (°C/yr)', cex.main = cexmain)])
invisible(trends[, hist(seas, main = 'Seasonality (°C)', cex.main = cexmain)])
invisible(trends[, hist(microclim, main = 'Microclimates (°C)', cex.main = cexmain)])
invisible(trends[, hist(Nspp, main = 'Species richness', cex.main = cexmain)])
invisible(trends[, hist(thermal_bias, main = 'Thermal bias (°C)', cex.main = cexmain)])
invisible(trends[, hist(npp, main = 'Net primary productivity', cex.main = cexmain)])
invisible(trends[, hist(veg, main = 'Vegetation index', cex.main = cexmain)])
invisible(trends[, hist(human_bowler, main = 'Human impact score (Bowler)', cex.main = cexmain)])
invisible(trends[, hist(human_venter, main = 'Human impact score (Venter)', cex.main = cexmain)])
invisible(trends[, hist(human_halpern, main = 'Human impact score (Halpern)', cex.main = cexmain)])

Scaled

# histograms to examine
cexmain = 0.6
par(mfrow = c(5,4))
invisible(trends[, hist(tempave.sc, main = 'Environmental temperature (°C)', cex.main = cexmain)])
invisible(trends[, hist(tempave_metab.sc, main = 'Metabolic temperature (°C)', cex.main = cexmain)])
invisible(trends[, hist(seas.sc, main = 'Seasonality (°C)', cex.main = cexmain)])
invisible(trends[, hist(microclim.sc, main = 'log Microclimates (°C)', cex.main = cexmain)])
invisible(trends[, hist(temptrend.sc, main = 'Temperature trend (°C/yr)', cex.main = cexmain)])
invisible(trends[, hist(temptrend_abs.sc, main = 'abs(Temperature trend) (°C/yr)', cex.main = cexmain)])
invisible(trends[, hist(mass.sc, main = 'log Mass (g)', cex.main = cexmain)])
invisible(trends[, hist(speed.sc, main = 'log Speed (km/hr)', cex.main = cexmain)])
invisible(trends[, hist(lifespan.sc, main = 'log Lifespan (yr)', cex.main = cexmain)])
invisible(trends[, hist(consumerfrac.sc, main = 'Consumers (fraction)', cex.main = cexmain)])
invisible(trends[, hist(endothermfrac.sc, main = 'Endotherms (fraction)', cex.main = cexmain)])
invisible(trends[, hist(nspp.sc, main = 'log Species richness', cex.main = cexmain)])
invisible(trends[, hist(thermal_bias.sc, main = 'Thermal bias (°C)', cex.main = cexmain)])
invisible(trends[, hist(npp.sc, main = 'log Net primary productivity', cex.main = cexmain)])
invisible(trends[, hist(veg.sc, main = 'log Vegetation index', cex.main = cexmain)])
invisible(trends[, hist(human_bowler.sc, main = 'log Human impact score (Bowler)', cex.main = cexmain)])
invisible(trends[, hist(human_footprint.sc, main = 'log Human impact score (Venter & Halpern)', cex.main = cexmain)])

Check correlations among variables. Pearson’s r is on the lower diagonal.

panel.cor <- function(x, y, digits = 2, prefix = "", cex.cor, ...)
{
    usr <- par("usr"); on.exit(par(usr))
    par(usr = c(0, 1, 0, 1))
    r <- cor(x, y, use = 'pairwise.complete.obs')
    txt <- format(c(r, 0.123456789), digits = digits)[1]
    txt <- paste0(prefix, txt)
    if(missing(cex.cor)) cex.cor <- 0.8/strwidth(txt)
    text(0.5, 0.5, txt) #, cex = cex.cor * r)
}
pairs(formula = ~ tempave.sc + tempave_metab.sc + seas.sc + microclim.sc + temptrend.sc + temptrend_abs.sc + mass.sc + speed.sc + lifespan.sc + consumerfrac.sc + endothermfrac.sc + nspp.sc + thermal_bias.sc + npp.sc + veg.sc + human_bowler.sc + human_footprint.sc, data = trends, gap = 1/10, cex = 0.2, col = '#00000022', lower.panel = panel.cor)

Mass and lifespan look tightly correlated, but r only 0.56…? Tempave_metab and lifespan don’t look tightly correlated, but r= -0.81 Tempave_metab and speed don’t look tightly correlated, but r= -0.83 Lifespan and speed don’t look tightly correlated, but r = 0.73

LS0tCnRpdGxlOiAiVHVybm92ZXIgY292YXJpYXRlIGRhdGEgcHJlcCIKb3V0cHV0OgogIGdpdGh1Yl9kb2N1bWVudDogZGVmYXVsdAogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKLS0tCgpgYGB7ciBzZXR1cH0KbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoYmVhbnBsb3QpICMgZm9yIGJlYW5wbG90cwpsaWJyYXJ5KGdyaWRFeHRyYSkgIyB0byBjb21iaW5lIGdncGxvdHMgdG9nZXRoZXIKbGlicmFyeShncmlkKSAjIHRvIGNvbWJpbmUgZ2dwbG90cyB0b2dldGhlcgoKCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gcnByb2pyb290OjpmaW5kX3JzdHVkaW9fcm9vdF9maWxlKCkpICMgdGVsbCBSU3R1ZGlvIHRvIHVzZSBwcm9qZWN0IHJvb3QgZGlyZWN0b3J5IGFzIHRoZSByb290IGZvciB0aGlzIG5vdGVib29rLiBOZWVkZWQgc2luY2Ugd2UgYXJlIHN0b3JpbmcgY29kZSBpbiBhIHNlcGFyYXRlIGRpcmVjdG9yeS4KYGBgCgojIyMgTG9hZCBkYXRhCmBgYHtyIGxvYWQgZGF0YX0KIyBCaW9UaW1lCmxvYWQoJ2RhdGEvYmlvdGltZV9ibG93ZXMvYnRfbWFsaW4uUmRhdGEnKQpidCA8LSBkYXRhLnRhYmxlKGJ0X21hbGluKTsgcm0oYnRfbWFsaW4pCgojIFRlbXBlcmF0dXJlIGF2ZXJhZ2UsIHRyZW5kcywgYW5kIHNlYXNvbmFsaXR5CnRlbXBlcmF0dXJlIDwtIGZyZWFkKCdvdXRwdXQvdGVtcGVyYXR1cmVfYnlyYXJlZnlJRC5jc3YuZ3onKQoKIyBtaWNyb2NsaW1hdGVzCm1pY3JvY2xpbSA8LSBmcmVhZCgnb3V0cHV0L21pY3JvY2xpbWF0ZXMuY3N2Lmd6JywgZHJvcCA9IDEpCgojIE5QUApucHAgPC0gZnJlYWQoJ291dHB1dC9ucHBsYW5kb2NlYW4uY3N2Lmd6JykKCiMgQm9keSBzaXplCmJzIDwtIGZyZWFkKCdvdXRwdXQvbWFzc19ieXJhcmVmeWlkLmNzdi5neicsIGRyb3AgPSAxKQpic1ssICc6PScoU1RVRFlfSUQgPSBOVUxMLCBSRUFMTSA9IE5VTEwsIHRheGFfbW9kID0gTlVMTCldICMgcmVtb3ZlIHVubmVjZXNzYXJ5IGNvbHVtbnMgCgojIE1vYmlsaXR5CnNwZWVkIDwtIGZyZWFkKCdvdXRwdXQvc3BlZWRfYnlyYXJlZnlJRC5jc3YuZ3onLCBkcm9wID0gMSkKc3BlZWRbLCAnOj0nKFNUVURZX0lEID0gTlVMTCwgUkVBTE0gPSBOVUxMLCB0YXhhX21vZCA9IE5VTEwpXSAjIHJlbW92ZSB1bm5lY2Vzc2FyeSBjb2x1bW5zIAoKIyBMaWZlc3Bhbgpsc3AgPC0gZnJlYWQoJ291dHB1dC9saWZlc3Bhbl9ieXJhcmVmeUlELmNzdi5neicpCgojIENUSQpjdGkgPC0gZnJlYWQoJ291dHB1dC9jdGlfYnlyYXJlZnlJRC5jc3YuZ3onKQogICAgCiMgY29uc3VtZXIgdnMuIHByb2R1Y2VyCmNvbnMgPC0gZnJlYWQoJ291dHB1dC9tZXRhYl9mZWVkX2J5c3BlY2llcy5jc3YuZ3onKQpjb25zZnJhYyA8LSBjb25zWywgLihjb25zZnJhYyA9IHN1bShmZWVkaW5nID09ICdjb25zdW1lcicpLy5OKSwgYnkgPSByYXJlZnlJRF0gIyBmcmFjdGlvbiBvZiBzcGVjaWVzIGluIGVhY2ggc3R1ZHkgdGhhdCBhcmUgY29uc3VtZXJzCgojIHJpY2huZXNzCnJpY2ggPC0gZnJlYWQoJ291dHB1dC9yaWNobmVzc19ieV9yYXJlZnlJRC5jc3YuZ3onKSAjIG51bWJlciBvZiBzcGVjaWVzCgojIGVuZG90aGVybSB2cy4gZWN0b3RoZXJtCmVuZG8gPC0gZnJlYWQoJ291dHB1dC9tZXRhYl9mZWVkX2J5c3BlY2llcy5jc3YuZ3onKSAjIGVuZG90aGVybSB2cy4gZWN0b3RoZXJtIGNsYXNzaWZpY2F0aW9ucwplbmRvZnJhYyA8LSBlbmRvWywgLihlbmRvZnJhYyA9IHN1bShtZXRhYiAhPSAnZWN0bycpLy5OKSwgYnkgPSByYXJlZnlJRF0Kcm0oZW5kbykKCiMgaHVtYW4gaW1wYWN0Cmh1bWFuIDwtIGZyZWFkKCdvdXRwdXQvaHVtYW5pbXBhY3RfYnlfcmFyZWZ5SUQuY3N2Lmd6JykKCiMgJXZlZwp2ZWcgPC0gYXMuZGF0YS50YWJsZShyZWFkUkRTKCdvdXRwdXQvdmN0X2J5X3JhcmVmeUlELnJkcycpKQp2ZWdbLCB2ZWcgOj0gKGB0cmVlIGNvdmVyICUgKG1lYW4pYCArIDAuNSAqIGBub24tdHJlZSB2ZWcuICUgKG1lYW4pYCkvMTAwXSAjIHZlZyBpbmRleCBmcm9tIDAgKGFsbCBub24tdmVnKSB0byAxIChhbGwgdHJlZSkuIE5vbi10cmVlIHZlZyBjb3VudHMgYXMgMC41LgpgYGAKCiMjIyBQbG90IGEgdHVybm92ZXIgZXhhbXBsZQpgYGB7ciBwbG90IHR1cm5vdmVyfQojYnRbLCAuKG4gPSAuTiksIGJ5ID0gcmFyZWZ5SURdW24gPiA1MCxdCgpnZ3Bsb3QoYnRbcmFyZWZ5SUQgPT0gJzMzOV8xMDg1NDc3J10sIGFlcyhZRUFSLCBKdHVfYmFzZSkpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nKSArCiAgICB4bGFiKCdZZWFyJykgKyB5bGFiKCdKYWNjYXJkIGRpc3NpbWlsYXJpdHknKQpgYGAKCiMjIyBBc3NlbWJsZSBkYXRhc2V0IG9mIGJldGEgZGl2ZXJzaXR5IHRyZW5kcyAodGVtcG9yYWwgdHVybm92ZXIpIGFuZCBjb3ZhcmlhdGVzCmBgYHtyIGFzc2VtYmxlIHRyZW5kc30KIyBjYWxjdWxhdGUgdGVtcG9yYWwgdHVybm92ZXIKY2FsY3RyZW5kIDwtIGZ1bmN0aW9uKHksIFlFQVIsIG5tID0gJ3knKXsgIyBmdW5jdGlvbiB0byBjYWxjIHRyZW5kcwogICMgdHVybiBvZmYgd2FybmluZ3MgZm9yIHRoZSBmb2xsb3dpbmcKICBkZWZhdWx0VyA8LSBnZXRPcHRpb24oIndhcm4iKQogIG9wdGlvbnMod2FybiA9IC0xKQogIAogIG1vZCA8LSBsbSh5IH4gWUVBUikKICBvdXQgPC0gbGlzdCh5ID0gY29lZihtb2QpWzJdLCAjIGNvZWYgZm9yIHRoZSBzbG9wZQogICAgICAgICAgICAgIHlfc2UgPSBzcXJ0KGRpYWcodmNvdihtb2QpKSlbMl0pICMgU0UKICBuYW1lcyhvdXQpIDwtIGMobm0sIHBhc3RlMChubSwgJ19zZScpKQogIG9wdGlvbnMod2FybiA9IGRlZmF1bHRXKQogIHJldHVybihvdXQpCn0KCiMgZnVuY3Rpb24gdG8gY2FsYyB0cmVuZHMsIHJlbW92aW5nIGZpcnN0IHllYXIgd2l0aCAwCmNhbGN0cmVuZHJlbTAgPC0gZnVuY3Rpb24oeSwgWUVBUiwgbm0gPSAneScpewogICMgdHVybiBvZmYgd2FybmluZ3MgZm9yIHRoZSBmb2xsb3dpbmcKICBkZWZhdWx0VyA8LSBnZXRPcHRpb24oIndhcm4iKQogIG9wdGlvbnMod2FybiA9IC0xKQogIAogIGlmKGxlbmd0aChZRUFSKT4yKXsKICAgIG8gPC0gb3JkZXIoWUVBUikKICAgIFlFQVIyIDwtIFlFQVJbb11bMjpsZW5ndGgoWUVBUildCiAgICB5MiA8LSB5W29dWzI6bGVuZ3RoKHkpXQogICAgCiAgICBpZihzdW0oIWlzLm5hKHkyKSkgPj0gMil7ICMgbWFrZSBzdXJlIGVub3VnaCB2YWx1ZXMgdG8gZml0IGEgbGluZQogICAgICBtb2QgPC0gbG0oeTIgfiBZRUFSMikKICAgICAgb3V0IDwtIGxpc3QoeSA9IGNvZWYobW9kKVsyXSwgIyBjb2VmIGZvciB0aGUgc2xvcGUKICAgICAgICAgICAgICAgICAgeV9zZSA9IHNxcnQoZGlhZyh2Y292KG1vZCkpKVsyXSkgIyBTRQogICAgICBuYW1lcyhvdXQpIDwtIGMobm0sIHBhc3RlMChubSwgJ19zZScpKQogICAgICBvcHRpb25zKHdhcm4gPSBkZWZhdWx0VykKICAgICAgcmV0dXJuKG91dCkKICAgICAgCiAgICB9IGVsc2UgewogICAgICBvdXQgPC0gbGlzdCh5ID0gTkFfcmVhbF8sIHlfc2UgPSBOQV9yZWFsXykKICAgICAgbmFtZXMob3V0KSA8LSBjKG5tLCBwYXN0ZTAobm0sICdfc2UnKSkKICAgICAgCiAgICAgIG9wdGlvbnMod2FybiA9IGRlZmF1bHRXKQogICAgICByZXR1cm4ob3V0KQogICAgfQogICAgCiAgfSBlbHNlIHsKICAgIG91dCA8LSBsaXN0KHkgPSBOQV9yZWFsXywgeV9zZSA9IE5BX3JlYWxfKQogICAgbmFtZXMob3V0KSA8LSBjKG5tLCBwYXN0ZTAobm0sICdfc2UnKSkKICAKICAgIG9wdGlvbnMod2FybiA9IGRlZmF1bHRXKQogICAgcmV0dXJuKG91dCkKICB9CiAgCgp9CgoKc2V0a2V5KGJ0LCBTVFVEWV9JRCwgcmFyZWZ5SUQsIFlFQVIpCgoKdHJlbmRzIDwtIGJ0WywgY2FsY3RyZW5kKEp0dV9iYXNlLCBZRUFSLCAnSnR1dHJlbmQnKSwgCiAgICBieSA9IC4oUkVBTE0sIEJpb21lLCB0YXhhX21vZCwgU1RVRFlfSUQsIHJhcmVmeUlELCByYXJlZnlJRF94LCByYXJlZnlJRF95KV0gIyBjYWxjdWxhdGUgdHJlbmQgaW4gSmFjY2FyZCB0dXJub3ZlciBmcm9tIGZpcnN0IHllYXIsIHBsdXMgU0VzCnRyZW5kczIgPC0gYnRbLCBjYWxjdHJlbmQoSmJldGFfYmFzZSwgWUVBUiwgJ0piZXRhdHJlbmQnKSwgCiAgICBieSA9IC4ocmFyZWZ5SUQpXSAjIGNhbGN1bGF0ZSB0cmVuZCBpbiB0b3RhbCBKYWNjYXJkJyBiZXRhIGRpdmVyc2l0eSdzIGZyb20gZmlyc3QgeWVhciwgCnRyZW5kczMgPC0gYnRbLCBjYWxjdHJlbmQoMS1Ib3JuX2Jhc2UsIFlFQVIsICdIb3JudHJlbmQnKSwgCiAgICBieSA9IC4ocmFyZWZ5SUQpXSAjIGNhbGN1bGF0ZSB0cmVuZCBpbiBIb3JuLU1vcmlzaXRhIGZyb20gZmlyc3QgeWVhci4gQ29udmVydCB0byBkaXNzaW1pbGFyaXR5LgojdHJlbmRzNCA8LSBidFssIC4oU3RyZW5kID0gY29lZihsbShJKGxvZyhTKSkgfiBZRUFSKSlbMl0pLCBieSA9IC4ocmFyZWZ5SUQpXSAjIHRyZW5kIGluIGxvZyhTKQoKdHJlbmRzNSA8LSBidFssIGNhbGN0cmVuZHJlbTAoSnR1X2Jhc2UsIFlFQVIsICdKdHV0cmVuZHJlbTAnKSwgCiAgICBieSA9IC4ocmFyZWZ5SUQpXSAjIGNhbGN1bGF0ZSB0cmVuZCBpbiBKYWNjYXJkIHR1cm5vdmVyIHdpdGhvdXQgZmlyc3QgeWVhcgp0cmVuZHM2IDwtIGJ0WywgY2FsY3RyZW5kcmVtMChKYmV0YV9iYXNlLCBZRUFSLCAnSmJldGF0cmVuZHJlbTAnKSwgCiAgICBieSA9IC4ocmFyZWZ5SUQpXQp0cmVuZHM3IDwtIGJ0WywgY2FsY3RyZW5kcmVtMCgxLUhvcm5fYmFzZSwgWUVBUiwgJ0hvcm50cmVuZHJlbTAnKSwgCiAgICBieSA9IC4ocmFyZWZ5SUQpXQoKCm55ckJUIDwtICBidFssIC4obnlyQlQgPSBsZW5ndGgoWUVBUiksIAogICAgICAgICAgICAgICAgIG1pbnlyQlQgPSBtaW4oWUVBUiksIAogICAgICAgICAgICAgICAgIG1heHlyQlQgPSBtYXgoWUVBUiksCiAgICAgICAgICAgICAgICAgbWVkaWFueXJCVCA9IG1lZGlhbihZRUFSKSwKICAgICAgICAgICAgICAgICBtZWFueXJCVCA9IG1lYW4oWUVBUikpLCAKICAgICAgICAgICAgIGJ5ID0gLihyYXJlZnlJRCldICMgbnVtYmVyIG9mIHllYXJzIGluIHRpbWUtc2VyaWVzCgp0cmVuZHMgPC0gbWVyZ2UodHJlbmRzLCB0cmVuZHMyKSAjIG1lcmdlIGluIHRvdGFsIEogYW5kIEhvcm4tTW9yaXNpdGEKdHJlbmRzIDwtIG1lcmdlKHRyZW5kcywgdHJlbmRzMykKdHJlbmRzIDwtIG1lcmdlKHRyZW5kcywgdHJlbmRzNSkKdHJlbmRzIDwtIG1lcmdlKHRyZW5kcywgdHJlbmRzNikKdHJlbmRzIDwtIG1lcmdlKHRyZW5kcywgdHJlbmRzNykKdHJlbmRzIDwtIG1lcmdlKHRyZW5kcywgbnlyQlQpCmBgYAoKQWRkIGNvdmFyaWF0ZXMKYGBge3IgYWRkIGNvdmFyaWF0ZSBkYXRhfQojIGFkZCBjb3ZhcmlhdGVzCnRyZW5kcyA8LSBtZXJnZSh0cmVuZHMsIHRlbXBlcmF0dXJlWywgLihyYXJlZnlJRCwgdGVtcGF2ZSwgdGVtcGF2ZV9tZXRhYiwgdGVtcHRyZW5kLCBzZWFzKV0sIGFsbC54ID0gVFJVRSwgYnkgPSAncmFyZWZ5SUQnKSAjIHRlbXBlcmF0dXJlIGF2ZSwgYXZlIG1ldGFib2xpYywgdHJlbmQsIGFuZCBzZWFzb25hbGl0eQp0cmVuZHMgPC0gbWVyZ2UodHJlbmRzLCBtaWNyb2NsaW1bLCAuKHJhcmVmeUlELCBtaWNyb2NsaW0gPSBUZW1wX3NkMjBrbSldLCBhbGwueCA9IFRSVUUsIGJ5ID0gJ3JhcmVmeUlEJykgIyBtaWNyb2NsaW1hdGVzCnRyZW5kcyA8LSBtZXJnZSh0cmVuZHMsIG5wcCwgYWxsLnggPSBUUlVFLCBieSA9ICdyYXJlZnlJRCcpICMgbnBwCnRyZW5kcyA8LSBtZXJnZSh0cmVuZHMsIGJzWywgLihyYXJlZnlJRCwgbWFzc19tZWFuX3dlaWdodCwgbWFzc19zZF93ZWlnaHQpXSwgYWxsLnggPSBUUlVFKSAjIGJvZHkgc2l6ZSBtYXNzIChnKQp0cmVuZHMgPC0gbWVyZ2UodHJlbmRzLCBzcGVlZFssIC4ocmFyZWZ5SUQsIHNwZWVkX21lYW5fd2VpZ2h0LCBzcGVlZF9zZF93ZWlnaHQpXSwgYWxsLnggPSBUUlVFKSAjIHNwZWVkIChrbS9ocikKdHJlbmRzIDwtIG1lcmdlKHRyZW5kcywgbHNwWywgLihyYXJlZnlJRCwgbGlmZXNwYW5fbWVhbl93ZWlnaHQsIGxpZmVzcGFuX3NkX3dlaWdodCldLCBhbGwueCA9IFRSVUUpICMgbGlmZXNwYW4gKHlyKQp0cmVuZHMgPC0gbWVyZ2UodHJlbmRzLCBjdGlbLCAuKHJhcmVmeUlELCB0aGVybWFsX2JpYXMpXSwgYWxsLnggPSBUUlVFKSAjIHRoZXJtYWwgYmlhcyAoZGVnQykKdHJlbmRzIDwtIG1lcmdlKHRyZW5kcywgY29uc2ZyYWMsIGFsbC54ID0gVFJVRSkgIyBmcmFjdGlvbiBjb25zdW1lcnMKdHJlbmRzIDwtIG1lcmdlKHRyZW5kcywgcmljaCwgYWxsLnggPSBUUlVFKSAjIHNwZWNpZXMgcmljaG5lc3MKdHJlbmRzIDwtIG1lcmdlKHRyZW5kcywgZW5kb2ZyYWMsIGFsbC54ID0gVFJVRSkgIyBlbmRvdGhlcm0gdnMuIGVjdG90aGVybQp0cmVuZHMgPC0gbWVyZ2UodHJlbmRzLCBodW1hblssIC4ocmFyZWZ5SUQsIGh1bWFuX2Jvd2xlciA9IGF0YywgaHVtYW5fdmVudGVyID0gaGZwLCBodW1hbl9oYWxwZXJuID0gaGltcCldLCBhbGwueCA9IFRSVUUpICMgaHVtYW4gaW1wYWN0CnRyZW5kcyA8LSBtZXJnZSh0cmVuZHMsIHZlZ1ssIC4ocmFyZWZ5SUQsIHZlZyA9IHZlZyldLCBhbGwueCA9IFRSVUUpICMgdmVnZXRhdGlvbiBpbmRleAp0cmVuZHNbUkVBTE0gPT0gJ01hcmluZScsIHZlZyA6PSAwXSAjIHZlZyBpbmRleCBpcyAwIGF0IHNlYQpgYGAKCkRvIHNvbWUgYmFzaWMgY2hlY2tzIG9mIHRoZSB0dXJub3ZlciBjYWxjdWxhdGlvbnMKYGBge3IgYmFzaWMgY2hlY2tzfQojIGJhc2ljIGNoZWNrcwp0cmVuZHMKdHJlbmRzWywgLihtaW5KdHUgPSBtaW4oSnR1dHJlbmQpLCBtYXhKdHUgPSBtYXgoSnR1dHJlbmQpLCBtaW5KYmUgPSBtaW4oSmJldGF0cmVuZCksIG1heEpiZSA9IG1heChKYmV0YXRyZW5kKSwgCiAgICAgICAgICAgbWluSG8gPSBtaW4oSG9ybnRyZW5kLCBuYS5ybSA9IFRSVUUpLCBtYXhIbyA9IG1heChIb3JudHJlbmQsIG5hLnJtID0gVFJVRSkpLCBieSA9IFJFQUxNXQp0cmVuZHNbLCAuKG5KdHUgPSBzdW0oSnR1dHJlbmQgPCAwKSksIGJ5ID0gUkVBTE1dICMgd2h5IGFyZSBzb21lIHR1cm5vdmVyIHRyZW5kcyA8IDA/IGZpcnN0IHllYXIgbW9yZSBkaXZlcmdlZCB0aGFuIGZ1dHVyZSB5ZWFycwp0cmVuZHNbLCAuKG5KID0gc3VtKEp0dXRyZW5kID4gMCkpLCBieSA9IFJFQUxNXQoKIyBudW1iZXIgb2Ygc3BlY2llcwp0cmVuZHNbLCBzdW1tYXJ5KE5zcHApXQp0cmVuZHNbLCBwbG90KE5zcHAsIEp0dXRyZW5kLCBsb2cgPSAneCcpXQpgYGAKClJlbW92ZSBzdHVkaWVzIHdpdGggb25seSAxIHNwZWNpZXMKYGBge3IgcmVtb3ZlIDEtc3BwIHN0dWRpZXN9Cm5yb3codHJlbmRzKQp0cmVuZHMgPC0gdHJlbmRzW05zcHAgPiAxLCBdCm5yb3codHJlbmRzKQpgYGAKClR1cm5vdmVyIGNhbGN1bGF0aW9ucyBhcmUgY29ycmVsYXRlZCwgdGhvdWdoIGxlc3Mgc28gZm9yIEhvcm4KYGBge3IgYmFzaWMgcGFpcndpc2UgZ3JhcGhzIG9mIHR1cm5vdmVyIG1ldHJpY3N9CiMgYXJlIHR1cm5vdmVyIGNhbGN1bGF0aW9ucyBjb3JyZWxhdGVkPwpnZ3Bsb3QodHJlbmRzLCBhZXMoSmJldGF0cmVuZCwgSnR1dHJlbmQpKSArCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC4zKSArCiAgICBnZW9tX3Ntb290aCgpCgpnZ3Bsb3QodHJlbmRzLCBhZXMoSmJldGF0cmVuZCwgSG9ybnRyZW5kKSkgKwogICAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMykgKwogICAgZ2VvbV9zbW9vdGgoKQoKYGBgClRlbXBvcmFsIHR1cm5vdmVyIGlzIG5vdCBhbGwgdGhhdCBjb3JyZWxhdGVkIGJldHdlZW4gaW5jbHVkaW5nIGZpcnN0IHllYXIgb3Igbm90LgpgYGB7ciB0dXJub3ZlciBtZXRyaWNzIHdpdGggYW5kIHdpdGhvdXQgZmlyc3QgeWVhcn0KZ2dwbG90KHRyZW5kcywgYWVzKEp0dXRyZW5kLCBKdHV0cmVuZHJlbTApKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMykgKwogIGdlb21fc21vb3RoKCkgKwogIGdlb21fYWJsaW5lKGEgPSAwLCBiID0gMSkKCmdncGxvdCh0cmVuZHMsIGFlcyhKYmV0YXRyZW5kLCBKYmV0YXRyZW5kcmVtMCkpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4zKSArCiAgZ2VvbV9zbW9vdGgoKSArCiAgZ2VvbV9hYmxpbmUoYSA9IDAsIGIgPSAxKQoKZ2dwbG90KHRyZW5kcywgYWVzKEhvcm50cmVuZCwgSG9ybnRyZW5kcmVtMCkpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4zKSArCiAgZ2VvbV9zbW9vdGgoKSArCiAgZ2VvbV9hYmxpbmUoYSA9IDAsIGIgPSAxKQoKYGBgCgojIyBDb21wYXJlIGNvdmFyaWF0ZXMgYWNyb3NzIHJlYWxtcwpgYGB7ciBjb21wYXJlIGFjcm9zcyByZWFsbXMsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD05fQppIDwtIHRyZW5kc1ssICFkdXBsaWNhdGVkKHJhcmVmeUlEKV07IHN1bShpKQpwYXIobWZyb3c9Yyg1LDMpKQpiZWFucGxvdChyYXJlZnlJRF95IH4gUkVBTE0sIGRhdGEgPSB0cmVuZHNbaSxdLCB3aGF0ID0gYygxLDEsMSwxKSwgY29sID0gYygiI0NBQjJENiIsICIjMzNBMDJDIiwgIiNCMkRGOEEiKSwgYm9yZGVyID0gIiNDQUIyRDYiLCB5bGFiID0gJ0xhdGl0dWRlIChkZWdOKScsIGxsID0gMC4wNSkKYmVhbnBsb3QodGVtcGF2ZSB+IFJFQUxNLCBkYXRhID0gdHJlbmRzW2ksXSwgd2hhdCA9IGMoMSwxLDEsMSksIGNvbCA9IGMoIiNDQUIyRDYiLCAiIzMzQTAyQyIsICIjQjJERjhBIiksIGJvcmRlciA9ICIjQ0FCMkQ2IiwgeWxhYiA9ICdUZW1wZXJhdHVyZSAoZGVnQyknLCBsbCA9IDAuMDUpCmJlYW5wbG90KHRlbXBhdmVfbWV0YWIgfiBSRUFMTSwgZGF0YSA9IHRyZW5kc1tpLF0sIHdoYXQgPSBjKDEsMSwxLDEpLCBjb2wgPSBjKCIjQ0FCMkQ2IiwgIiMzM0EwMkMiLCAiI0IyREY4QSIpLCBib3JkZXIgPSAiI0NBQjJENiIsIHlsYWIgPSAnTWV0YWJvbGljIFRlbXBlcmF0dXJlIChkZWdDKScsIGxsID0gMC4wNSwgYncgPSAnbnJkMCcpICMgbnJkMCBiYW5kd2lkdGggdG8gY2FsY3VsYXRpb24gZ2FwCmJlYW5wbG90KHNlYXMgfiBSRUFMTSwgZGF0YSA9IHRyZW5kc1tpLF0sIHdoYXQgPSBjKDEsMSwxLDEpLCBjb2wgPSBjKCIjQ0FCMkQ2IiwgIiMzM0EwMkMiLCAiI0IyREY4QSIpLCBib3JkZXIgPSAiI0NBQjJENiIsIHlsYWIgPSAnU2Vhc29uYWxpdHkgKGRlZ0MpJywgbGwgPSAwLjA1KQpiZWFucGxvdChtaWNyb2NsaW0gfiBSRUFMTSwgZGF0YSA9IHRyZW5kc1tpLF0sIHdoYXQgPSBjKDEsMSwxLDEpLCBjb2wgPSBjKCIjQ0FCMkQ2IiwgIiMzM0EwMkMiLCAiI0IyREY4QSIpLCBib3JkZXIgPSAiI0NBQjJENiIsIHlsYWIgPSAnTWljcm9jbGltYXRlcyAoZGVnQyknLCBsbCA9IDAuMDUpCmJlYW5wbG90KHRlbXB0cmVuZCB+IFJFQUxNLCBkYXRhID0gdHJlbmRzW2ksXSwgd2hhdCA9IGMoMSwxLDEsMSksIGNvbCA9IGMoIiNDQUIyRDYiLCAiIzMzQTAyQyIsICIjQjJERjhBIiksIGJvcmRlciA9ICIjQ0FCMkQ2IiwgeWxhYiA9ICdUZW1wZXJhdHVyZSB0cmVuZCAoZGVnQy95ciknLCBsbCA9IDAuMDUpCmJlYW5wbG90KG1hc3NfbWVhbl93ZWlnaHQgfiBSRUFMTSwgZGF0YSA9IHRyZW5kc1tpLF0sIHdoYXQgPSBjKDEsMSwxLDEpLCBjb2wgPSBjKCIjQ0FCMkQ2IiwgIiMzM0EwMkMiLCAiI0IyREY4QSIpLCBib3JkZXIgPSAiI0NBQjJENiIsIHlsYWIgPSAnTWFzcyAoZyknLCBsbCA9IDAuMDUsIGxvZyA9ICd5JykKYmVhbnBsb3Qoc3BlZWRfbWVhbl93ZWlnaHQgKzEgfiBSRUFMTSwgZGF0YSA9IHRyZW5kc1tpLF0sIHdoYXQgPSBjKDEsMSwxLDEpLCBjb2wgPSBjKCIjQ0FCMkQ2IiwgIiMzM0EwMkMiLCAiI0IyREY4QSIpLCBib3JkZXIgPSAiI0NBQjJENiIsIHlsYWIgPSAnU3BlZWQgKGttL2hyKScsIGxsID0gMC4wNSwgbG9nID0gJ3knKQpiZWFucGxvdChsaWZlc3Bhbl9tZWFuX3dlaWdodCB+IFJFQUxNLCBkYXRhID0gdHJlbmRzW2ksXSwgd2hhdCA9IGMoMSwxLDEsMSksIGNvbCA9IGMoIiNDQUIyRDYiLCAiIzMzQTAyQyIsICIjQjJERjhBIiksIGJvcmRlciA9ICIjQ0FCMkQ2IiwgeWxhYiA9ICdMaWZlc3BhbiAoeXIpJywgbGwgPSAwLjA1LCBsb2cgPSAneScpCiNiZWFucGxvdChjb25zZnJhYyB+IFJFQUxNLCBkYXRhID0gdHJlbmRzW2ksXSwgd2hhdCA9IGMoMSwxLDEsMSksIGNvbCA9IGMoIiNDQUIyRDYiLCAiIzMzQTAyQyIsICIjQjJERjhBIiksIGJvcmRlciA9ICIjQ0FCMkQ2IiwgeWxhYiA9ICdDb25zdW1lcnMgKGZyYWN0aW9uKScsIGxsID0gMC4wNSwgbG9nID0gJycpICMgdG9vIHNwYXJzZQojYmVhbnBsb3QoZW5kb2ZyYWMgfiBSRUFMTSwgZGF0YSA9IHRyZW5kc1tpLF0sIHdoYXQgPSBjKDEsMSwxLDEpLCBjb2wgPSBjKCIjQ0FCMkQ2IiwgIiMzM0EwMkMiLCAiI0IyREY4QSIpLCBib3JkZXIgPSAiI0NBQjJENiIsIHlsYWIgPSAnRW5kb3RoZXJtcyAoZnJhY3Rpb24pJywgbGwgPSAwLjA1LCBsb2cgPSAnJykgIyB0b28gc3BhcnNlCmJlYW5wbG90KE5zcHAgfiBSRUFMTSwgZGF0YSA9IHRyZW5kc1tpLF0sIHdoYXQgPSBjKDEsMSwxLDEpLCBjb2wgPSBjKCIjQ0FCMkQ2IiwgIiMzM0EwMkMiLCAiI0IyREY4QSIpLCBib3JkZXIgPSAiI0NBQjJENiIsIHlsYWIgPSAnTnVtYmVyIG9mIHNwZWNpZXMnLCBsbCA9IDAuMDUsIGxvZyA9ICd5JykKYmVhbnBsb3QodGhlcm1hbF9iaWFzIH4gUkVBTE0sIGRhdGEgPSB0cmVuZHNbaSAmICFpcy5uYSh0aGVybWFsX2JpYXMpLF0sIHdoYXQgPSBjKDEsMSwxLDEpLCBjb2wgPSBjKCIjQ0FCMkQ2IiwgIiMzM0EwMkMiLCAiI0IyREY4QSIpLCBib3JkZXIgPSAiI0NBQjJENiIsIHlsYWIgPSAnVGhlcm1hbCBiaWFzIChkZWdDKScsIGxsID0gMC4wNSkKYmVhbnBsb3QobnBwIH4gUkVBTE0sIGRhdGEgPSB0cmVuZHNbaSxdLCB3aGF0ID0gYygxLDEsMSwxKSwgY29sID0gYygiI0NBQjJENiIsICIjMzNBMDJDIiwgIiNCMkRGOEEiKSwgYm9yZGVyID0gIiNDQUIyRDYiLCB5bGFiID0gJ05QUCcsIGxsID0gMC4wNSkKYmVhbnBsb3QodmVnIH4gUkVBTE0sIGRhdGEgPSB0cmVuZHNbaSAmIFJFQUxNICE9J01hcmluZScsXSwgd2hhdCA9IGMoMSwxLDEsMSksIGNvbCA9IGMoIiNDQUIyRDYiLCAiIzMzQTAyQyIsICIjQjJERjhBIiksIGJvcmRlciA9ICIjQ0FCMkQ2IiwgeWxhYiA9ICdOUFAnLCBsbCA9IDAuMDUpCgpgYGAKCk1hcmluZSBhcmUgaW4gZ2VuZXJhbGx5IHdhcm1lciBsb2NhdGlvbnMgKHNlYXdhdGVyIGRvZXNuJ3QgZnJlZXplKQpNYXJpbmUgaGF2ZSBtdWNoIGxvd2VyIHNlYXNvbmFsaXR5LgpNYXJpbmUgYW5kIGZyZXNod2F0ZXIgaGF2ZSBzb21lIHZlcnkgc21hbGwgbWFzc2VzIChwbGFua3RvbiksIGJ1dCBtdWNoIG9mIGRhdGFzZXQgaXMgc2ltaWxhciB0byB0ZXJyZXN0cmlhbC4KTWFyaW5lIGhhcyBhIGxvdCBvZiBzbG93LCBjcmF3bGluZyBvcmdhbmlzbXMsIGJ1dCBsYW5kIGhhcyBwbGFudHMuIExhbmQgYWxzbyBoYXMgYmlyZHMgKGZhc3QpLgoKCgoKCgojIyBQbG90IHR1cm5vdmVyIHZzLiB0ZW1wZXJhdHVyZQpgYGB7ciBwbG90IHR1cm5vdmVyIHZzIHRlbXAgdHJlbmQsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQgPSA4LCBmaWcud2lkdGggPSA5LH0KcDEgPC0gZ2dwbG90KHRyZW5kcywgYWVzKHRlbXB0cmVuZCwgSnR1dHJlbmQsIGNvbG9yID0gUkVBTE0sIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ1RlbXBlcmF0dXJlIHRyZW5kICjCsEMveXIpJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kJywgdGl0bGUgPSAnQWxsJykKCiMgSmFjY2FyZCB0b3RhbCB0cmVuZCB2cy4gdGVtcGVyYXR1cmUgdHJlbmQgKGFjcm9zcyBhbGwgeWVhcnMpCnAyIDwtIGdncGxvdCh0cmVuZHMsIGFlcyh0ZW1wdHJlbmQsIEpiZXRhdHJlbmQsIGNvbG9yID0gUkVBTE0sIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ1RlbXBlcmF0dXJlIHRyZW5kICjCsEMveWVhciknLCB5ID0gJ0phY2NhcmQgdG90YWwgdGVtcG9yYWwgdHJlbmQnKQoKIyBIb3JuLU1vcmlzaXRhIHR1cm5vdmVyIHRyZW5kIHZzLiB0ZW1wZXJhdHVyZSB0cmVuZCAoYWNyb3NzIGFsbCB5ZWFycykKcDMgPC0gZ2dwbG90KHRyZW5kcywgYWVzKHRlbXB0cmVuZCwgSG9ybnRyZW5kLCBjb2xvciA9IFJFQUxNLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIGxhYnMoeCA9ICdUZW1wZXJhdHVyZSB0cmVuZCAowrBDL3llYXIpJywgeSA9ICdNb3Jpc2l0YS1Ib3JuIHRlbXBvcmFsIHR1cm5vdmVyJykKCiMgc2FtZSwgYnV0IG9ubHkgdHMgPj0gNSB5cnMKcDQgPC0gZ2dwbG90KHRyZW5kc1tueXJCVCA+PSA1LCBdLCBhZXModGVtcHRyZW5kLCBKdHV0cmVuZCwgY29sb3IgPSBSRUFMTSwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUsIG5hLnJtID0gVFJVRSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2FtJywgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIiksIG5hLnJtID0gVFJVRSkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKyAKICBsYWJzKHggPSAnVGVtcGVyYXR1cmUgdHJlbmQgKMKwQy95ciknLCB5ID0gJ0phY2NhcmQgdHVybm92ZXIgdGVtcG9yYWwgdHJlbmQnLCB0aXRsZSA9ICc+PSA1IHlycycpCgpwNSA8LSBnZ3Bsb3QodHJlbmRzW255ckJUID49IDUsIF0sIGFlcyh0ZW1wdHJlbmQsIEpiZXRhdHJlbmQsIGNvbG9yID0gUkVBTE0sIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ1RlbXBlcmF0dXJlIHRyZW5kICjCsEMveWVhciknLCB5ID0gJ0phY2NhcmQgdG90YWwgdGVtcG9yYWwgdHJlbmQnKQoKcDYgPC0gZ2dwbG90KHRyZW5kc1tueXJCVCA+PSA1LCBdLCBhZXModGVtcHRyZW5kLCBIb3JudHJlbmQsIGNvbG9yID0gUkVBTE0sIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ1RlbXBlcmF0dXJlIHRyZW5kICjCsEMveWVhciknLCB5ID0gJ01vcmlzaXRhLUhvcm4gdGVtcG9yYWwgdHVybm92ZXInKQoKIyBzYW1lLCBidXQgcmVtb3ZpbmcgeWVhciAxCnA3IDwtIGdncGxvdCh0cmVuZHMsIGFlcyh0ZW1wdHJlbmQsIEp0dXRyZW5kcmVtMCwgY29sb3IgPSBSRUFMTSwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUsIG5hLnJtID0gVFJVRSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2FtJywgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIiksIG5hLnJtID0gVFJVRSkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKyAKICBsYWJzKHggPSAnVGVtcGVyYXR1cmUgdHJlbmQgKMKwQy95ciknLCB5ID0gJ0phY2NhcmQgdHVybm92ZXIgdGVtcG9yYWwgdHJlbmQgdy9vdXQgeWVhciAxJywgdGl0bGUgPSAnV2l0aG91dCB5ZWFyIDEnKQoKcDggPC0gZ2dwbG90KHRyZW5kcywgYWVzKHRlbXB0cmVuZCwgSmJldGF0cmVuZHJlbTAsIGNvbG9yID0gUkVBTE0sIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ1RlbXBlcmF0dXJlIHRyZW5kICjCsEMveWVhciknLCB5ID0gJ0phY2NhcmQgdG90YWwgdGVtcG9yYWwgdHJlbmQgdy9vdXQgeWVhciAxJykKCnA5IDwtIGdncGxvdCh0cmVuZHMsIGFlcyh0ZW1wdHJlbmQsIEhvcm50cmVuZHJlbTAsIGNvbG9yID0gUkVBTE0sIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ1RlbXBlcmF0dXJlIHRyZW5kICjCsEMveWVhciknLCB5ID0gJ01vcmlzaXRhLUhvcm4gdGVtcG9yYWwgdHVybm92ZXIgdy9vdXQgeWVhciAxJykKCgpncmlkLmFycmFuZ2UocDEsIHA0LCBwNywgcDIsIHA1LCBwOCwgcDMsIHA2LCBwOSwgbmNvbCA9IDMpCmBgYAoKIyMjIFRpbWUtc2VyaWVzIGxlbmd0aCBhbmQgdGVtcGVyYXR1cmUgdHJlbmQ/CmBgYHtyIHRzIGxlbmd0aCBhbmQgdGVtcCB0cmVuZH0KZ2dwbG90KHRyZW5kcywgYWVzKHRlbXB0cmVuZCwgbnlyQlQpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aCgpICsKICBzY2FsZV95X2xvZzEwKCkKYGBgCgojIyBQbG90IHR1cm5vdmVyIHZzLiBleHBsYW5hdG9yeSB2YXJpYWJsZXMKTGluZXMgYXJlIGdncGxvdCBzbW9vdGhlciBmaXRzLgpgYGB7ciBwbG90IHR1cm5vdmVyIHYgZXhwbGFuYXRvcnkgdmFycywgZWNobz1GQUxTRSwgZmlnLmhlaWdodCA9IDE2LCBmaWcud2lkdGggPSA5LH0KCnAxIDwtIGdncGxvdCh0cmVuZHMsIGFlcyhSRUFMTSwgSnR1dHJlbmQpKSArCiAgZ2VvbV9ib3hwbG90KG5hLnJtID0gVFJVRSkgKyAKICBsYWJzKHggPSAnUmVhbG0nLCB5ID0gJ0phY2NhcmQgdHVybm92ZXIgdGVtcG9yYWwgdHJlbmQnKQoKcDIgPC0gZ2dwbG90KHRyZW5kcywgYWVzKHRlbXBhdmUsIEp0dXRyZW5kLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBSRUFMTSksIHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUsIGNvbG9yID0gJ2JsYWNrJykgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKyAKICBsYWJzKHggPSAnVGVtcGVyYXR1cmUgKMKwQyknLCB5ID0gJ0phY2NhcmQgdHVybm92ZXIgdGVtcG9yYWwgdHJlbmQnKQoKcDMgPC0gZ2dwbG90KHRyZW5kcywgYWVzKHRlbXBhdmVfbWV0YWIsIEp0dXRyZW5kLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBSRUFMTSksIHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUsIGNvbG9yID0gJ2JsYWNrJykgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKyAKICBsYWJzKHggPSAnTWV0YWJvbGljIHRlbXBlcmF0dXJlICjCsEMpJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kJykKCnA0IDwtIGdncGxvdCh0cmVuZHMsIGFlcyhzZWFzLCBKdHV0cmVuZCwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUkVBTE0pLCBzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFLCBjb2xvciA9ICdibGFjaycpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ1NlYXNvbmFsaXR5ICjCsEMpJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kJykKCnA1IDwtIGdncGxvdCh0cmVuZHMsIGFlcyhtaWNyb2NsaW0sIEp0dXRyZW5kLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBSRUFMTSksIHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUsIGNvbG9yID0gJ2JsYWNrJykgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKyAKICBzY2FsZV94X2xvZzEwKCkgKwogIGxhYnMoeCA9ICdNaWNyb2NsaW1hdGUgYXZhaWxhYmlsaXR5ICjCsEMpJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kJykKCnA2IDwtIGdncGxvdCh0cmVuZHMsIGFlcyhtYXNzX21lYW5fd2VpZ2h0LCBKdHV0cmVuZCwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUkVBTE0pLCBzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFLCBjb2xvciA9ICdibGFjaycpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgc2NhbGVfeF9sb2cxMCgpICsKICBsYWJzKHggPSAnTWFzcyAoZykpJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kJykKCnA3IDwtIGdncGxvdCh0cmVuZHMsIGFlcyhzcGVlZF9tZWFuX3dlaWdodCsxLCBKdHV0cmVuZCwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUkVBTE0pLCBzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFLCBjb2xvciA9ICdibGFjaycpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgc2NhbGVfeF9sb2cxMCgpICsKICBsYWJzKHggPSAnU3BlZWQgKGttIC8gaHIpKScsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcpCgpwOCA8LSBnZ3Bsb3QodHJlbmRzLCBhZXMobGlmZXNwYW5fbWVhbl93ZWlnaHQsIEp0dXRyZW5kLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBSRUFMTSksIHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLCBuYS5ybSA9IFRSVUUsIGNvbG9yID0gJ2JsYWNrJykgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKyAKICBzY2FsZV94X2xvZzEwKCkgKwogIGxhYnMoeCA9ICdMaWZlc3BhbiAoeXIpKScsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcpCgpwOSA8LSBnZ3Bsb3QodHJlbmRzLCBhZXMoY29uc2ZyYWMsIEp0dXRyZW5kLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBSRUFMTSksIHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIsIGsgPSAzKSwgbmEucm0gPSBUUlVFLCBjb2xvciA9ICdibGFjaycpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ0ZyYWN0aW9uIGNvbnN1bWVycycsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcpCgpwMTAgPC0gZ2dwbG90KHRyZW5kcywgYWVzKGVuZG9mcmFjLCBKdHV0cmVuZCwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUkVBTE0pLCBzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiLCBrID0gMyksIG5hLnJtID0gVFJVRSwgY29sb3IgPSAnYmxhY2snKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIGxhYnMoeCA9ICdGcmFjdGlvbiBlbmRvdGhlcm1zJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kJykKCnAxMSA8LSBnZ3Bsb3QodHJlbmRzLCBhZXMoTnNwcCwgSnR1dHJlbmQsIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IFJFQUxNKSwgc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUsIG5hLnJtID0gVFJVRSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2FtJywgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIiksIG5hLnJtID0gVFJVRSwgY29sb3IgPSAnYmxhY2snKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIHNjYWxlX3hfbG9nMTAoKSArCiAgbGFicyh4ID0gJ051bWJlciBvZiBzcGVjaWVzJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kJykKCnAxMiA8LSBnZ3Bsb3QodHJlbmRzLCBhZXModGhlcm1hbF9iaWFzLCBKdHV0cmVuZCwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUkVBTE0pLCBzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiKSwgbmEucm0gPSBUUlVFLCBjb2xvciA9ICdibGFjaycpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ1RoZXJtYWwgYmlhcyAowrBDKScsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcpCgpwMTMgPC0gZ2dwbG90KHRyZW5kcywgYWVzKG5wcCwgSnR1dHJlbmQsIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IFJFQUxNKSwgc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUsIG5hLnJtID0gVFJVRSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2FtJywgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIiksIG5hLnJtID0gVFJVRSwgY29sb3IgPSAnYmxhY2snKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIHNjYWxlX3hfbG9nMTAoKSArCiAgbGFicyh4ID0gJ05ldCBwcmltYXJ5IHByb2R1Y3Rpdml0eSAobWcgQyAvIG0yIC8gZGF5KScsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcpCgpwMTQgPC0gZ2dwbG90KHRyZW5kcywgYWVzKHZlZywgSnR1dHJlbmQsIGNvbG9yID0gUkVBTE0sIHNpemUgPSBueXJCVCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAwLjIsIGFscGhhID0gMC41LCBuYS5ybSA9IFRSVUUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2dhbScsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIsIGsgPSA1KSwgbmEucm0gPSBUUlVFKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlNldDEiKSArIAogIGxhYnMoeCA9ICdWZWdldGF0aW9uIHNjb3JlJywgeSA9ICdKYWNjYXJkIHR1cm5vdmVyIHRlbXBvcmFsIHRyZW5kJykKCnAxNSA8LSBnZ3Bsb3QodHJlbmRzLCBhZXMoaHVtYW5fYm93bGVyLCBKdHV0cmVuZCwgY29sb3IgPSBSRUFMTSwgc2l6ZSA9IG55ckJUKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDAuMiwgYWxwaGEgPSAwLjUsIG5hLnJtID0gVFJVRSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnZ2FtJywgZm9ybXVsYSA9IHkgfiBzKHgsIGJzID0gImNzIiwgayA9IDUpLCBuYS5ybSA9IFRSVUUpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iU2V0MSIpICsgCiAgbGFicyh4ID0gJ0Jvd2xlciBodW1hbiBpbXBhY3Qgc2NvcmUnLCB5ID0gJ0phY2NhcmQgdHVybm92ZXIgdGVtcG9yYWwgdHJlbmQnKQoKcDE2IDwtIGdncGxvdCh0cmVuZHMsIGFlcyhodW1hbl92ZW50ZXIsIEp0dXRyZW5kLCBjb2xvciA9IFJFQUxNLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiLCBrID0gNSksIG5hLnJtID0gVFJVRSkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKyAKICBsYWJzKHggPSAnc2NhbGVkIEh1bWFuIGltcGFjdCBzY29yZSAoVmVudGVyKScsIHkgPSAnSmFjY2FyZCB0dXJub3ZlciB0ZW1wb3JhbCB0cmVuZCcpCgpwMTcgPC0gZ2dwbG90KHRyZW5kcywgYWVzKGh1bWFuX2hhbHBlcm4sIEp0dXRyZW5kLCBjb2xvciA9IFJFQUxNLCBzaXplID0gbnlyQlQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMC4yLCBhbHBoYSA9IDAuNSwgbmEucm0gPSBUUlVFKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdnYW0nLCBmb3JtdWxhID0geSB+IHMoeCwgYnMgPSAiY3MiLCBrID0gNSksIG5hLnJtID0gVFJVRSkgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKyAKICBsYWJzKHggPSAnc2NhbGVkIEh1bWFuIGltcGFjdCBzY29yZSAoSGFscGVybiknLCB5ID0gJ0phY2NhcmQgdHVybm92ZXIgdGVtcG9yYWwgdHJlbmQnKQoKCmdyaWQuYXJyYW5nZShwMSwgcDIsIHAzLCBwNCwgcDUsIHA2LCBwNywgcDgsIHA5LCBwMTAsIHAxMSwgcDEyLCBwMTMsIHAxNCwgcDE1LCBwMTYsIHAxNywgbmNvbCA9IDIpCmBgYAoKU3Ryb25nIHRyZW5kcyB3aXRoIHRlbXBlcmF0dXJlIGNoYW5nZSwgYnV0IHRyZW5kcyBhcmUgcHJldHR5IHN5bW1ldHJpYyBhcm91bmQgbm8gdHJlbmQgaW4gdGVtcGVyYXR1cmUsIHdoaWNoIGltcGxpZXMgd2FybWluZyBvciBjb29saW5nIGRyaXZlcyBzaW1pbGFyIGRlZ3JlZSBvZiBjb21tdW5pdHkgdHVybm92ZXIuClNvbWUgaW5kaWNhdGlvbiBvZiBsZXNzIHR1cm5vdmVyIGZvciBsYXJnZXIgb3JnYW5pc21zIChtYXNzKQpIaWdoZXIgdHVybm92ZXIgb24gbGFuZCB3aXRoIGhpZ2hlciBzZWFzb25hbGl0eT8KTW9yZSB0dXJub3ZlciBmb3Igc2hvcnRlci1saXZlZCBvcmdhbmlzbXM/Ck5vIHJlYWxseSBjbGVhciBkaWZmZXJlbmNlcyBhbW9uZyByZWFsbXMuCgojIyMgV3JpdGUgb3V0CmBgYHtyIHdyaXRlIG91dH0Kd3JpdGUuY3N2KHRyZW5kcywgZ3pmaWxlKCdvdXRwdXQvdHVybm92ZXJfd19jb3ZhcmlhdGVzLmNzdi5neicpLCByb3cubmFtZXMgPSBGQUxTRSkKYGBgCgoKIyMjIFVzZWZ1bCB2YXJpYWJsZXMKYGBge3IgdXNlZnVsIHZhcnN9CiMgcmVhbG0gdGhhdCBjb21iaW5lZCBUZXJyZXN0cmlhbCBhbmQgRnJlc2h3YXRlciwgZm9yIGludGVyYWN0aW5nIHdpdGggaHVtYW4gaW1wYWN0CnRyZW5kc1ssIFJFQUxNMiA6PSBSRUFMTV0KbGV2ZWxzKHRyZW5kcyRSRUFMTTIpID0gbGlzdChUZXJyRnJlc2ggPSAiRnJlc2h3YXRlciIsIFRlcnJGcmVzaCA9ICJUZXJyZXN0cmlhbCIsIE1hcmluZSA9ICJNYXJpbmUiKQoKIyBncm91cCBNYXJpbmUgaW52ZXJ0ZWJyYXRlcy9wbGFudHMgaW4gd2l0aCBBbGwKdHJlbmRzWywgdGF4YV9tb2QyIDo9IHRheGFfbW9kXQp0cmVuZHNbdGF4YV9tb2QgPT0gJ01hcmluZSBpbnZlcnRlYnJhdGVzL3BsYW50cycsIHRheGFfbW9kMiA6PSAnQWxsJ10KYGBgCgoKIyMjIExvZy10cmFuc2Zvcm0gc29tZSB2YXJpYWJsZXMsIHRoZW4gY2VudGVyIGFuZCBzY2FsZS4gCmBgYCB7ciBjZW50ZXIgYW5kIHNjYWxlfQp0cmVuZHNbLCB0ZW1wYXZlLnNjIDo9IHNjYWxlKHRlbXBhdmUpXQp0cmVuZHNbLCB0ZW1wYXZlX21ldGFiLnNjIDo9IHNjYWxlKHRlbXBhdmVfbWV0YWIpXQp0cmVuZHNbLCBzZWFzLnNjIDo9IHNjYWxlKHNlYXMpXQp0cmVuZHNbLCBtaWNyb2NsaW0uc2MgOj0gc2NhbGUobG9nKG1pY3JvY2xpbSkpXQp0cmVuZHNbLCB0ZW1wdHJlbmQuc2MgOj0gc2NhbGUodGVtcHRyZW5kLCBjZW50ZXIgPSBGQUxTRSldCnRyZW5kc1ssIHRlbXB0cmVuZF9hYnMuc2MgOj0gc2NhbGUoYWJzKHRlbXB0cmVuZCksIGNlbnRlciA9IEZBTFNFKV0gIyBkbyBub3QgY2VudGVyLCBzbyB0aGF0IDAgaXMgc3RpbGwgMCB0ZW1wZXJhdHVyZSBjaGFuZ2UKdHJlbmRzWywgbWFzcy5zYyA6PSBzY2FsZShsb2cobWFzc19tZWFuX3dlaWdodCkpXQp0cmVuZHNbLCBzcGVlZC5zYyA6PSBzY2FsZShsb2coc3BlZWRfbWVhbl93ZWlnaHQrMSkpXQp0cmVuZHNbLCBsaWZlc3Bhbi5zYyA6PSBzY2FsZShsb2cobGlmZXNwYW5fbWVhbl93ZWlnaHQpKV0KdHJlbmRzWywgY29uc3VtZXJmcmFjLnNjIDo9IHNjYWxlKGNvbnNmcmFjKV0KdHJlbmRzWywgZW5kb3RoZXJtZnJhYy5zYyA6PSBzY2FsZShlbmRvZnJhYyldCnRyZW5kc1ssIG5zcHAuc2MgOj0gc2NhbGUobG9nKE5zcHApKV0KdHJlbmRzWywgdGhlcm1hbF9iaWFzLnNjIDo9IHNjYWxlKHRoZXJtYWxfYmlhcyldCnRyZW5kc1ssIG5wcC5zYyA6PSBzY2FsZShsb2cobnBwKSldCnRyZW5kc1ssIHZlZy5zYyA6PSBzY2FsZShsb2codmVnKzEpKV0KdHJlbmRzWywgaHVtYW5fYm93bGVyLnNjIDo9IHNjYWxlKGxvZyhodW1hbl9ib3dsZXIrMSkpLCBieSA9IFJFQUxNMl0gIyBzZXBhcmF0ZSBzY2FsaW5nIGJ5IHJlYWxtCnRyZW5kc1tSRUFMTTIgPT0gJ1RlcnJGcmVzaCcsIGh1bWFuX2Zvb3RwcmludC5zYyA6PSBzY2FsZShsb2coaHVtYW5fdmVudGVyKzEpKV0KdHJlbmRzW1JFQUxNMiA9PSAnTWFyaW5lJywgaHVtYW5fZm9vdHByaW50LnNjIDo9IHNjYWxlKGxvZyhodW1hbl9oYWxwZXJuKSldCmBgYAoKCiMjIyBEbyB0aGUgdmFyaWFibGVzIGxvb2sgb2s/CiMjIyMgVW5zY2FsZWQKYGBge3IgaGlzdG9ncmFtcyB1bnNjYWxlZCwgZmlnLmhlaWdodCA9IDl9CiMgaGlzdG9ncmFtcyB0byBleGFtaW5lCmNleG1haW4gPSAwLjYKcGFyKG1mcm93ID0gYyg1LDQpKQppbnZpc2libGUodHJlbmRzWywgaGlzdChtaW55ckJULCBtYWluID0gJ1N0YXJ0IHllYXInLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QobWF4eXJCVCAtIG1pbnlyQlQsIG1haW4gPSAnRHVyYXRpb24gKHllYXJzKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChueXJCVCwgbWFpbiA9ICdOdW1iZXIgb2Ygc2FtcGxlZCB5ZWFycycsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChtYXNzX21lYW5fd2VpZ2h0LCBtYWluID0gJ01hc3MgKGcpJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KHNwZWVkX21lYW5fd2VpZ2h0LCBtYWluID0gJ1NwZWVkIChrbS9ociknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QobGlmZXNwYW5fbWVhbl93ZWlnaHQsIG1haW4gPSAnTGlmZXNwYW4gKHlyKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdCh0ZW1wYXZlX21ldGFiLCBtYWluID0gJ01ldGFib2xpYyB0ZW1wZXJhdHVyZSAowrBDKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChjb25zZnJhYywgbWFpbiA9ICdDb25zdW1lcnMgKGZyYWN0aW9uKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChlbmRvZnJhYywgbWFpbiA9ICdFbmRvdGhlcm1zIChmcmFjdGlvbiknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QodGVtcGF2ZSwgbWFpbiA9ICdFbnZpcm9ubWVudGFsIHRlbXBlcmF0dXJlICjCsEMpJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KHRlbXB0cmVuZCwgbWFpbiA9ICdUZW1wZXJhdHVyZSB0cmVuZCAowrBDL3lyKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChzZWFzLCBtYWluID0gJ1NlYXNvbmFsaXR5ICjCsEMpJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KG1pY3JvY2xpbSwgbWFpbiA9ICdNaWNyb2NsaW1hdGVzICjCsEMpJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KE5zcHAsIG1haW4gPSAnU3BlY2llcyByaWNobmVzcycsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdCh0aGVybWFsX2JpYXMsIG1haW4gPSAnVGhlcm1hbCBiaWFzICjCsEMpJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KG5wcCwgbWFpbiA9ICdOZXQgcHJpbWFyeSBwcm9kdWN0aXZpdHknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QodmVnLCBtYWluID0gJ1ZlZ2V0YXRpb24gaW5kZXgnLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QoaHVtYW5fYm93bGVyLCBtYWluID0gJ0h1bWFuIGltcGFjdCBzY29yZSAoQm93bGVyKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChodW1hbl92ZW50ZXIsIG1haW4gPSAnSHVtYW4gaW1wYWN0IHNjb3JlIChWZW50ZXIpJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KGh1bWFuX2hhbHBlcm4sIG1haW4gPSAnSHVtYW4gaW1wYWN0IHNjb3JlIChIYWxwZXJuKScsIGNleC5tYWluID0gY2V4bWFpbildKQoKYGBgCgojIyMjIFNjYWxlZApgYGB7ciBoaXN0b2dyYW1zIHNjYWxlZCwgZmlnLmhlaWdodCA9IDl9CiMgaGlzdG9ncmFtcyB0byBleGFtaW5lCmNleG1haW4gPSAwLjYKcGFyKG1mcm93ID0gYyg1LDQpKQppbnZpc2libGUodHJlbmRzWywgaGlzdCh0ZW1wYXZlLnNjLCBtYWluID0gJ0Vudmlyb25tZW50YWwgdGVtcGVyYXR1cmUgKMKwQyknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QodGVtcGF2ZV9tZXRhYi5zYywgbWFpbiA9ICdNZXRhYm9saWMgdGVtcGVyYXR1cmUgKMKwQyknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3Qoc2Vhcy5zYywgbWFpbiA9ICdTZWFzb25hbGl0eSAowrBDKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChtaWNyb2NsaW0uc2MsIG1haW4gPSAnbG9nIE1pY3JvY2xpbWF0ZXMgKMKwQyknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QodGVtcHRyZW5kLnNjLCBtYWluID0gJ1RlbXBlcmF0dXJlIHRyZW5kICjCsEMveXIpJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KHRlbXB0cmVuZF9hYnMuc2MsIG1haW4gPSAnYWJzKFRlbXBlcmF0dXJlIHRyZW5kKSAowrBDL3lyKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChtYXNzLnNjLCBtYWluID0gJ2xvZyBNYXNzIChnKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChzcGVlZC5zYywgbWFpbiA9ICdsb2cgU3BlZWQgKGttL2hyKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChsaWZlc3Bhbi5zYywgbWFpbiA9ICdsb2cgTGlmZXNwYW4gKHlyKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChjb25zdW1lcmZyYWMuc2MsIG1haW4gPSAnQ29uc3VtZXJzIChmcmFjdGlvbiknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QoZW5kb3RoZXJtZnJhYy5zYywgbWFpbiA9ICdFbmRvdGhlcm1zIChmcmFjdGlvbiknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKaW52aXNpYmxlKHRyZW5kc1ssIGhpc3QobnNwcC5zYywgbWFpbiA9ICdsb2cgU3BlY2llcyByaWNobmVzcycsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdCh0aGVybWFsX2JpYXMuc2MsIG1haW4gPSAnVGhlcm1hbCBiaWFzICjCsEMpJywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KG5wcC5zYywgbWFpbiA9ICdsb2cgTmV0IHByaW1hcnkgcHJvZHVjdGl2aXR5JywgY2V4Lm1haW4gPSBjZXhtYWluKV0pCmludmlzaWJsZSh0cmVuZHNbLCBoaXN0KHZlZy5zYywgbWFpbiA9ICdsb2cgVmVnZXRhdGlvbiBpbmRleCcsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChodW1hbl9ib3dsZXIuc2MsIG1haW4gPSAnbG9nIEh1bWFuIGltcGFjdCBzY29yZSAoQm93bGVyKScsIGNleC5tYWluID0gY2V4bWFpbildKQppbnZpc2libGUodHJlbmRzWywgaGlzdChodW1hbl9mb290cHJpbnQuc2MsIG1haW4gPSAnbG9nIEh1bWFuIGltcGFjdCBzY29yZSAoVmVudGVyICYgSGFscGVybiknLCBjZXgubWFpbiA9IGNleG1haW4pXSkKCmBgYAoKCgojIyMgQ2hlY2sgY29ycmVsYXRpb25zIGFtb25nIHZhcmlhYmxlcy4gUGVhcnNvbidzIHIgaXMgb24gdGhlIGxvd2VyIGRpYWdvbmFsLgpgYGB7ciBwYWlycywgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEwfQpwYW5lbC5jb3IgPC0gZnVuY3Rpb24oeCwgeSwgZGlnaXRzID0gMiwgcHJlZml4ID0gIiIsIGNleC5jb3IsIC4uLikKewogICAgdXNyIDwtIHBhcigidXNyIik7IG9uLmV4aXQocGFyKHVzcikpCiAgICBwYXIodXNyID0gYygwLCAxLCAwLCAxKSkKICAgIHIgPC0gY29yKHgsIHksIHVzZSA9ICdwYWlyd2lzZS5jb21wbGV0ZS5vYnMnKQogICAgdHh0IDwtIGZvcm1hdChjKHIsIDAuMTIzNDU2Nzg5KSwgZGlnaXRzID0gZGlnaXRzKVsxXQogICAgdHh0IDwtIHBhc3RlMChwcmVmaXgsIHR4dCkKICAgIGlmKG1pc3NpbmcoY2V4LmNvcikpIGNleC5jb3IgPC0gMC44L3N0cndpZHRoKHR4dCkKICAgIHRleHQoMC41LCAwLjUsIHR4dCkgIywgY2V4ID0gY2V4LmNvciAqIHIpCn0KcGFpcnMoZm9ybXVsYSA9IH4gdGVtcGF2ZS5zYyArIHRlbXBhdmVfbWV0YWIuc2MgKyBzZWFzLnNjICsgbWljcm9jbGltLnNjICsgdGVtcHRyZW5kLnNjICsgdGVtcHRyZW5kX2Ficy5zYyArIG1hc3Muc2MgKyBzcGVlZC5zYyArIGxpZmVzcGFuLnNjICsgY29uc3VtZXJmcmFjLnNjICsgZW5kb3RoZXJtZnJhYy5zYyArIG5zcHAuc2MgKyB0aGVybWFsX2JpYXMuc2MgKyBucHAuc2MgKyB2ZWcuc2MgKyBodW1hbl9ib3dsZXIuc2MgKyBodW1hbl9mb290cHJpbnQuc2MsIGRhdGEgPSB0cmVuZHMsIGdhcCA9IDEvMTAsIGNleCA9IDAuMiwgY29sID0gJyMwMDAwMDAyMicsIGxvd2VyLnBhbmVsID0gcGFuZWwuY29yKQoKYGBgCgpNYXNzIGFuZCBsaWZlc3BhbiBsb29rIHRpZ2h0bHkgY29ycmVsYXRlZCwgYnV0IHIgb25seSAwLjU2Li4uPwpUZW1wYXZlX21ldGFiIGFuZCBsaWZlc3BhbiBkb24ndCBsb29rIHRpZ2h0bHkgY29ycmVsYXRlZCwgYnV0IHI9IC0wLjgxIApUZW1wYXZlX21ldGFiIGFuZCBzcGVlZCBkb24ndCBsb29rIHRpZ2h0bHkgY29ycmVsYXRlZCwgYnV0IHI9IC0wLjgzIApMaWZlc3BhbiBhbmQgc3BlZWQgZG9uJ3QgbG9vayB0aWdodGx5IGNvcnJlbGF0ZWQsIGJ1dCByID0gMC43Mwo=